package com.r2coding.web.exception;

import com.r2coding.core.exception.Pan4jException;
import com.r2coding.core.exception.Pan4jFrameworkException;
import com.r2coding.core.response.ResponseCode;
import com.r2coding.core.response.Result;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

/**
 * @author 98k灬
 * @version v1.0.0
 * @Description : 全局异常处理器
 * @Create on : 2023/9/17 10:24
 **/
@RestControllerAdvice
public class Pan4jExceptionHandler {
    @ExceptionHandler(value = Pan4jException.class)
    public Result<?> pan4jException(Pan4jException exception) {
        return Result.error(exception.getCode(), exception.getMessage());
    }

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result<?> methodArgumentNotValidException(MethodArgumentNotValidException exception) {
        ObjectError objectError = exception.getBindingResult().getAllErrors().stream().findFirst().get();
        return Result.error(ResponseCode.ERROR_PARAM.getCode(), objectError.getDefaultMessage());
    }

    @ExceptionHandler(value = ConstraintViolationException.class)
    public Result<?> constraintViolationException(ConstraintViolationException exception) {
        ConstraintViolation<?> violation = exception.getConstraintViolations().stream().findFirst().get();
        return Result.error(ResponseCode.ERROR_PARAM.getCode(), violation.getMessage());
    }

    @ExceptionHandler(value = MissingServletRequestParameterException.class)
    public Result<?> missingServletRequestParameterException(MissingServletRequestParameterException exception) {
        return Result.error(ResponseCode.ERROR_PARAM);
    }

    @ExceptionHandler(value = IllegalStateException.class)
    public Result<?> illegalStateException(IllegalStateException exception) {
        return Result.error(ResponseCode.ERROR_PARAM);
    }

    @ExceptionHandler(value = BindException.class)
    public Result<?> bindException(BindException exception) {
        FieldError fieldError = exception.getBindingResult().getFieldErrors().stream().findFirst().get();
        return Result.error(ResponseCode.ERROR_PARAM.getCode(), fieldError.getDefaultMessage());
    }

    @ExceptionHandler(value = Pan4jFrameworkException.class)
    public Result<?> bindException(Pan4jFrameworkException exception) {
        return Result.error(ResponseCode.ERROR.getCode(), exception.getMessage());
    }

    @ExceptionHandler(value = RuntimeException.class)
    public Result<?> runtimeException(RuntimeException exception) {
        return Result.error(ResponseCode.ERROR.getCode(), exception.getMessage());
    }
}
